using System;
using System.Collections;
using System.Threading.Tasks;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;
using Unity.VisualScripting;
using Object = UnityEngine.Object;

public class AssetManager : MonoSingleton<AssetManager>
{
    // 普通资源缓存
    private Dictionary<string, UnityEngine.Object> prefabCache = new Dictionary<string, UnityEngine.Object>();
    // 图集缓存
    private Dictionary<string, SpriteAtlas> atlasCache = new Dictionary<string, SpriteAtlas>();
    //UI预设缓存
    private Dictionary<string, UnityEngine.Object> uiPrefabCache = new Dictionary<string, UnityEngine.Object>();
    

    private const string PREFAB_BASE_PATH = "Prefabs/";    // 普通资源路径
    private const string ATLAS_BASE_PATH = "Art/SpriteAtlas/"; // 图集路径
    private const string UI_PREFAB_BASE_PATH = "Prefabs/UI";      // UI预设路径
    private const string DIALUGUE_SO_PATH = "SOData/Dialogue";      // SO文件路径

    protected override void Awake()
    {
        
    }

    #region 普通预设资源处理
    public T LoadPrefab<T>(string prefabName) where T : Object
    {
        if (string.IsNullOrEmpty(prefabName))
        {
            Debug.LogError("AssetManager: Prefab name is null or empty.");
            return null;
        }

        // 检查缓存
        if (prefabCache.TryGetValue(prefabName, out var cachedPrefab))
        {
            return cachedPrefab as T;
        }

        // 构建完整路径
        string prefabPath = PREFAB_BASE_PATH + prefabName;

        // 加载资源
        T prefab = Resources.Load<T>(prefabPath);
        if (prefab == null)
        {
            Debug.LogError($"AssetManager: Failed to load prefab at path: {prefabPath}");
            return null;
        }

        // 缓存资源
        prefabCache[prefabName] = prefab;
        return prefab;
    }
    /// <summary>
    /// 异步加载普通预设资源（如 GameObject）
    /// </summary>
    /// <param name="prefabName">预设名称</param>
    /// <typeparam name="T">资源类型</typeparam>
    /// <returns>加载的预设资源</returns>
    public  async Task<T> LoadPrefabAsync<T>(string prefabName) where T : Object
    {
        if (string.IsNullOrEmpty(prefabName))
        {
            Debug.LogError("AssetManager: Prefab name is null or empty.");
            return null;
        }

        // 检查缓存
        if (prefabCache.TryGetValue(prefabName, out var cachedPrefab))
        {
            return cachedPrefab as T;
        }

        // 构建完整路径
        string prefabPath = PREFAB_BASE_PATH + prefabName;

        // 创建 ResourceRequest
        ResourceRequest request = Resources.LoadAsync<T>(prefabPath);
        while (!request.isDone)
        {
            await Task.Delay(1);
        }

        // 检查加载结果
        if (request.asset == null)
        {
            Debug.LogError($"AssetManager: Failed to load prefab asynchronously at path: {prefabPath}");
            return null;
        }

        // 缓存资源
        prefabCache[prefabName] = request.asset;
        Debug.Log($"----------------------{request.asset}");
        return request.asset as T; // 返回加载的资源
    }
    /// <summary>
    /// 清除普通资源缓存
    /// </summary>
    public void ClearPrefabCache()
    {
        prefabCache.Clear();
        Debug.Log("AssetManager: Cleared prefab cache.");
    }
    #endregion
    
    #region 图集资源处理

    /// <summary>
    /// 从图集中加载 Sprite
    /// </summary>
    /// <param name="atlasName">图集名称</param>
    /// <param name="spriteName">图集中 Sprite 的名称</param>
    /// <returns>加载的 Sprite</returns>
    public Sprite LoadSprite(string atlasName, string spriteName)
    {
        if (string.IsNullOrEmpty(atlasName) || string.IsNullOrEmpty(spriteName))
        {
            Debug.LogError("AssetManager: Atlas name or sprite name is null or empty.");
            return null;
        }

        // 检查图集缓存
        if (!atlasCache.TryGetValue(atlasName, out var atlas))
        {
            // 构建完整的图集路径
            string atlasPath = ATLAS_BASE_PATH + atlasName;

            // 加载图集
            atlas = Resources.Load<SpriteAtlas>(atlasPath);
            if (atlas == null)
            {
                Debug.LogError($"AssetManager: Failed to load sprite atlas: {atlasName}");
                return null;
            }

            // 缓存图集
            atlasCache[atlasName] = atlas;
        }
        // 从图集中获取精灵
        Sprite sprite = atlas.GetSprite(spriteName);
        if (sprite == null)
        {
            Debug.LogError($"AssetManager: Sprite '{spriteName}' not found in atlas '{atlasName}'");
            return null;
        }
        return sprite;
    }

    /// <summary>
    /// 异步从图集中加载 Sprite
    /// </summary>
    /// <param name="atlasName">图集名称</param>
    /// <param name="spriteName">图集中 Sprite 的名称</param>
    /// <returns>加载的 Sprite</returns>
    public async Task<Sprite> LoadSpriteAsync(string atlasName, string spriteName)
    {
        if (string.IsNullOrEmpty(atlasName) || string.IsNullOrEmpty(spriteName))
        {
            Debug.LogError("AssetManager: Atlas name or sprite name is null or empty.");
            return null;
        }

        // 检查图集缓存
        if (!atlasCache.TryGetValue(atlasName, out var atlas))
        {
            // 构建完整的图集路径
            string atlasPath = ATLAS_BASE_PATH + atlasName;

            // 异步加载图集
            ResourceRequest request = Resources.LoadAsync<SpriteAtlas>(atlasPath);
            while (!request.isDone)
            {
                await Task.Yield();
            }

            if (request.asset == null)
            {
                Debug.LogError($"AssetManager: Failed to load sprite atlas: {atlasName}");
                return null;
            }

            atlas = request.asset as SpriteAtlas;

            // 缓存图集
            atlasCache[atlasName] = atlas;
        }

        // 从图集中获取精灵
        Sprite sprite = atlas.GetSprite(spriteName);
        if (sprite == null)
        {
            Debug.LogError($"AssetManager: Sprite '{spriteName}' not found in atlas '{atlasName}'");
            return null;
        }

        return sprite;
    }

    /// <summary>
    /// 清除图集资源缓存
    /// </summary>
    public void ClearAtlasCache()
    {
        atlasCache.Clear();
        Debug.Log("AssetManager: Cleared atlas cache.");
    }

    #endregion

    #region UI预设资源处理
    /// <summary>
    /// 加载UI预设资源
    /// </summary>
    /// <param name="uiPrefabName">UI预设名称</param>
    /// <typeparam name="T">资源类型</typeparam>
    /// <returns>加载的UI预设资源</returns>
    public T LoadUIPrefab<T>(string uiPrefabName) where T : Object
    {
        if (string.IsNullOrEmpty(uiPrefabName))
        {
            Debug.LogError("AssetManager: UI Prefab name is null or empty.");
            return null;
        }

        // 检查缓存
        if (uiPrefabCache.TryGetValue(uiPrefabName, out var cachedUIPrefab))
        {
            
            return Instantiate(cachedUIPrefab) as T;
        }

        // 构建完整路径
        string uiPrefabPath = UI_PREFAB_BASE_PATH + "/" +uiPrefabName;

        // 加载资源
        T uiPrefab = Resources.Load<T>(uiPrefabPath);
        if (uiPrefab == null)
        {
            Debug.LogError($"AssetManager: Failed to load UI prefab at path: {uiPrefabPath}");
            return null;
        }

        // 缓存资源
        uiPrefabCache[uiPrefabName] = uiPrefab;
        return Instantiate(uiPrefab);
    }

    /// <summary>
    /// 异步加载UI预设资源
    /// </summary>
    /// <param name="uiPrefabName">UI预设名称</param>
    /// <typeparam name="T">资源类型</typeparam>
    /// <returns>加载的UI预设资源</returns>
    public async Task<T> LoadUIPrefabAsync<T>(string uiPrefabName) where T : Object
    {
        if (string.IsNullOrEmpty(uiPrefabName))
        {
            Debug.LogError("AssetManager: UI Prefab name is null or empty.");
            return null;
        }

        // 检查缓存
        if (uiPrefabCache.TryGetValue(uiPrefabName, out var cachedUIPrefab))
        {
            return cachedUIPrefab as T;
        }

        // 构建完整路径
        string uiPrefabPath = UI_PREFAB_BASE_PATH + uiPrefabName;

        // 异步加载资源
        ResourceRequest request = Resources.LoadAsync<T>(uiPrefabPath);
        while (!request.isDone)
        {
            await Task.Yield();
        }

        if (request.asset == null)
        {
            Debug.LogError($"AssetManager: Failed to load UI prefab asynchronously at path: {uiPrefabPath}");
            return null;
        }

        // 缓存资源
        uiPrefabCache[uiPrefabName] = request.asset;

        return request.asset as T;
    }

    /// <summary>
    /// 清除UI预设资源缓存
    /// </summary>
    public void ClearUIPrefabCache()
    {
        uiPrefabCache.Clear();
        Debug.Log("AssetManager: Cleared UI prefab cache.");
    }

    #endregion
    
    /// <summary>
    /// 异步加载一个 GameObject 资源，用于多次实例化使用。
    /// 如果传入了 MonoBehaviour，则会为其添加 AssetUnloader 组件以自动管理资源释放。
    /// </summary>
    /// <param name="assetName">资源的名称（Addressables 中定义的路径）</param>
    /// <param name="monoBehaviour">_需要绑定 AssetUnloader 的 MonoBehaviour 对象，可为 null</param>
    /// <returns>返回加载完成的 GameObject 引用</returns>
    public async Task<GameObject> LoadAssetMultiInstantiate(string assetName,MonoBehaviour monoBehaviour)
    {
        var assetRef = await LoadPrefabAsync<GameObject>(assetName);
        // if(monoBehaviour!= null)monoBehaviour.gameObject.AddComponent<AssetUnloader>().SetData(assetRef);
        Debug.Log($"assetRef    --------{assetRef}");
        return assetRef;
    }
    public async Task LoadAssetMultiInstantiate(string assetName,MonoBehaviour monoBehaviour,Action<GameObject> action)
    {
        GameObject _prefab = await LoadAssetMultiInstantiate(assetName,monoBehaviour);
        if(_prefab != null)
        {
            UtilityMain.SafePostEvent(action,_prefab);
        }
    }
    public static GameObject InstantiateInner(GameObject prefab,Transform parent = null)
    {
        if(prefab != null)
        {
            var clonePrefab = (GameObject)GameObject.Instantiate(prefab);
            if(parent != null)
            {
                clonePrefab.transform.SetParent(parent);
                clonePrefab.transform.localScale = Vector3.one;
                clonePrefab.transform.localPosition = Vector3.zero;
            }
            return clonePrefab;
        }

        return null; 
    }
}
